home *** CD-ROM | disk | FTP | other *** search
/ Super PC 34 / Super PC 34 (Shareware).iso / spc / SONIDO / AMUSIC11 / SOURCES / ASM / AMDOBJ.ASM next >
Encoding:
Assembly Source File  |  1995-12-28  |  23.1 KB  |  1,260 lines

  1. ;Source for the Amusic-Playerobject
  2. ;6.12.1995 by Conqueror / ε£¥$$ì$
  3. ;
  4. ;Note: Diz was written for packed modules!
  5. ;      And please do not use modules bigger than 64k !!! It doesn't work!
  6. ;
  7. ;This player stores all datas and stuff into one userdefined-workbuffer.
  8. ;No other dos memory is needed!!!
  9. ;
  10.  
  11. JUMPS
  12.  
  13. PUBLIC _InitAdlib
  14. PUBLIC _AdlibPlayer
  15. PUBLIC _StopAdlib
  16. PUBLIC _AdlibState
  17.  
  18. FreqStart       =       156h            ; low end of frequency in each octave
  19. FreqEnd         =       2aeh            ; high end of frequency in each octave
  20. FreqRange       =       FreqEnd-FreqStart
  21.  
  22.  
  23. WrkBuff_TrackBase       equ 0           ;Pointer to each track
  24. WrkBuff_TrackPtr        equ 480h        ;Offsets in current tracks
  25. WrkBuff_TrackDelay      equ 492h        ;Delay for current tracks
  26. WrkBuff_CurrPtn         equ 49Bh        ;
  27. WrkBuff_CurrLine        equ 49Ch        ;
  28. WrkBuff_SongDelay       equ 49Dh        ;
  29. WrkBuff_CurrSpeed       equ 49Eh        ;
  30. WrkBuff_CurrEvent       equ 49Fh        ;privat Buffer!!!
  31. WrkBuff_LastEvent       equ 4A4h        ;
  32. WrkBuff_CarrVol         equ 510h
  33. WrkBuff_ModVol          equ 519h
  34.  
  35. WrkBuffSize equ 522h
  36.  
  37.  
  38. .model small
  39. .code
  40. main:
  41. .186
  42.  
  43. _AdlibState     db 0            ;set to zero if adlib not detected!!!
  44.  
  45.  
  46. ev_pitch        equ 0
  47. ev_oct          equ 1
  48. ev_sam          equ 2
  49. ev_cmd          equ 3
  50. ev_params       equ 4
  51.  
  52. ev_vol          equ 5   ;lastvol
  53. ev_arpeggio     equ 6
  54. ev_pitching     equ 7
  55. ev_tpdest       equ 9
  56. ev_lastparams   equ 11  ;for TonePortamento and stuff!!!
  57. LastEventSize   equ 12
  58.  
  59.  
  60. FreqParams      dw 343,363,385,408,432,458,485,514,544,577,611,647
  61.  
  62. oldint08        dw 0,0
  63.  
  64. ModPtr          dw 0,0
  65. WrkPtr          dw 0,0
  66.  
  67.  
  68.  
  69. ;----- InitAdlib ----------
  70. ;
  71. ; This proc fills the work buffer with pointers, defaults and stuff.
  72. ; Call this to create a buffer for a tune!!!
  73. ;
  74.  
  75.  
  76. ;ds:si = Modulepointer
  77. ;es:di = Workbuffer
  78. ;al = playmode (0=interrupt 1=polling)
  79.  
  80. _InitAdlib proc near
  81.     pusha
  82.     push    ax
  83.  
  84.     mov     cs:[ModPtr],si
  85.     mov     ax,ds
  86.     mov     cs:[ModPtr+2],ax
  87.     mov     cs:[WrkPtr],di
  88.     mov     ax,es
  89.     mov     cs:[WrkPtr+2],ax
  90.  
  91.  
  92.     call    Adlib_Reset
  93.  
  94. ;---- Clear Workbuffer
  95.     push    di
  96.     xor     ax,ax
  97.     mov     cx,WrkBuffSize/2
  98.     rep     stosw
  99.     pop     di
  100.  
  101. ;---- Init trackpointer
  102.     mov     bl,ds:[si+933]          ;number of patterns
  103.     inc     bl
  104.     xor     bh,bh
  105.     imul    bx,18
  106.     lea     si,[si+bx+1072]         ;offset of the tracks
  107.     lodsw
  108.     mov     cx,ax
  109. ia_GetTrackPtrLoop:
  110.     lodsw                           ;read trackposition
  111.     mov     bx,ax
  112.     add     bx,bx
  113.     mov     es:[di+bx],si           ;store pointer into trackptrtab!
  114.     xor     dl,dl
  115. ia_SearchNextTrack:
  116.     lodsb
  117.     test    al,128
  118.     jnz     ia_Jump
  119.     lodsw
  120.     inc     dl
  121.     jmp     ia_GetNextEvent
  122. ia_Jump:
  123.     and     al,127
  124.     add     dl,al
  125. ia_GetNextEvent:
  126.     cmp     dl,64
  127.     jb      ia_SearchNextTrack
  128.     loop    ia_GetTrackPtrLoop
  129.  
  130.     mov     word ptr es:[di+WrkBuff_SongDelay],0606h   ;default tempo!!!
  131.  
  132.     pop     ax
  133.     mov     cs:[irqmod],al
  134.     cmp     al,1
  135.     jz      ia_PollingMode
  136.  
  137. ;---- Init the Timer-IRQ
  138.     cli
  139.     mov     ax,3508h
  140.     int     21h
  141.     mov     cs:[oldint08],bx
  142.     mov     cs:[oldint08+2],es
  143.  
  144.     mov     ax,2508h
  145.     push    cs
  146.     pop     ds
  147.     mov     dx,offset TimerProc
  148.     int     21h
  149.  
  150.     mov     ax,5D37h        ;50Hz
  151.     out     40h,al
  152.     mov     al,ah
  153.     out     40h,al
  154.     sti
  155.  
  156. ia_PollingMode:
  157.  
  158.     popa
  159.     ret
  160. _InitAdlib endp
  161.  
  162.  
  163. _StopAdlib proc near
  164.     push    ds
  165.  
  166.     cmp     cs:[irqmod],1
  167.     jz      sa_Polling
  168.  
  169.     cli
  170.     mov     al,-1
  171.     out     40h,al
  172.     out     40h,al
  173.  
  174.     mov     ax,2508h
  175.     push    cs:[oldint08+2]
  176.     pop     ds
  177.     mov     dx,cs:[oldint08]
  178.     int     21h
  179.     sti
  180.  
  181. sa_Polling:
  182.     call    Adlib_Reset
  183.     pop ds
  184.     ret
  185. _StopAdlib endp
  186.  
  187.  
  188. irqmod  db 0
  189.  
  190. TimerProc proc near
  191.     push    ax ds es si di
  192.     lds     si,dword ptr cs:[ModPtr]
  193.     les     di,dword ptr cs:[WrkPtr]
  194.     call    _AdlibPlayer
  195.     mov     al,20h
  196.     out     20h,al
  197.     pop     di si es ds ax
  198.     iret
  199. TimerProc endp
  200.  
  201.  
  202.  
  203.  
  204. ;------ Adlib Player --------
  205. ;
  206. ; This is the mainfunction of the player jump into this code 50 times a sec.
  207. ; (or what ever your songtempo is)
  208. ;
  209.  
  210.  
  211.  
  212. ;ds:si = Modulepointer
  213. ;es:di = Workbuffer
  214.  
  215.  
  216. _AdlibPlayer proc near
  217.     cmp     cs:[_AdlibState],0
  218.     jz      ap_NoAdlibPresent
  219.     pusha
  220.     mov     al,byte ptr es:[di+WrkBuff_SongDelay]
  221.     dec     al
  222.     jnz     ap_JustDoTheFX
  223.  
  224.     mov     al,byte ptr es:[di+WrkBuff_CurrSpeed]
  225.     mov     byte ptr es:[di+WrkBuff_SongDelay],al
  226.     cmp     byte ptr es:[di+WrkBuff_CurrLine],0
  227.     jnz     ap_ContPtn
  228.     call    CalcTrackPtr
  229. ap_ContPtn:
  230.  
  231.     mov     cs:[breakstate],0
  232.  
  233.     xor     cx,cx
  234. ap_ChannelLoop:
  235.     mov     bx,cx
  236.  
  237.     mov     al,byte ptr es:WrkBuff_TrackDelay[di+bx]
  238.     and     al,127
  239.     jz      ap_TryToGetEvent
  240.     dec     byte ptr es:WrkBuff_TrackDelay[di+bx]
  241.     jmp     ap_StillWaiting
  242.  
  243. ap_TryToGetEvent:
  244.     mov     byte ptr es:WrkBuff_TrackDelay[di+bx],0
  245.     add     bx,bx
  246.     mov     bp,es:WrkBuff_TrackPtr[di+bx]
  247.  
  248.     mov     al,ds:[bp]      ;Is it a delay??? Then wait!!!
  249.     test    al,128
  250.     jz      ap_NewEvent
  251.     dec     al
  252.     inc     word ptr es:WrkBuff_TrackPtr[di+bx]
  253.     mov     bx,cx
  254.     mov     byte ptr es:WrkBuff_TrackDelay[di+bx],al
  255.     jmp     ap_StillWaiting
  256.  
  257. ap_NewEvent:
  258.     add     word ptr es:WrkBuff_TrackPtr[di+bx],3
  259.  
  260. ;---- Decode current event
  261.  
  262.  
  263.     mov     byte ptr es:[di+WrkBuff_CurrEvent+ev_params],al
  264.     mov     ax,ds:[bp+1]
  265.     mov     dl,al
  266.     and     dl,0Fh
  267.     mov     byte ptr es:[di+WrkBuff_CurrEvent+ev_cmd],dl
  268.     mov     dx,ax
  269.     shr     dx,4
  270.     and     dl,11111b
  271.     mov     byte ptr es:[di+WrkBuff_CurrEvent+ev_sam],dl
  272.     mov     al,ah
  273.     shr     al,1
  274.     and     al,7
  275.     mov     byte ptr es:[di+WrkBuff_CurrEvent+ev_oct],al
  276.     shr     ah,4
  277.     mov     byte ptr es:[di+WrkBuff_CurrEvent+ev_pitch],ah
  278.  
  279.  
  280. ;############# update channel !! ###########
  281.  
  282.     imul    bp,cx,LastEventSize
  283.  
  284. ;--- change instrument???
  285.     mov     al,es:[di+WrkBuff_CurrEvent+ev_sam]
  286.     or      al,al
  287.     jz      uc_NoInstrChange
  288.     mov     es:[di+WrkBuff_LastEvent+ev_sam+bp],al  ;update instrument
  289.     mov     byte ptr es:[di+WrkBuff_LastEvent+ev_vol+bp],3Fh
  290.  
  291. uc_NoInstrChange:
  292.  
  293. ;--- change the pitch???
  294.     mov     al,es:[di+WrkBuff_CurrEvent+ev_pitch]
  295.     or      al,al
  296.     jz      uc_NoPitch
  297.     cmp     byte ptr es:[di+WrkBuff_CurrEvent+ev_cmd],8
  298.     jz      uc_NoPitch
  299.     mov     es:[di+WrkBuff_LastEvent+ev_pitch+bp],al    ;update pitch
  300.     mov     al,es:[di+WrkBuff_CurrEvent+ev_oct]
  301.     mov     es:[di+WrkBuff_LastEvent+ev_oct+bp],al
  302.  
  303. ;--- play the new note!
  304.     mov     word ptr es:[di+WrkBuff_LastEvent+ev_Pitching+bp],0
  305.     jmp     uc_Ready
  306.  
  307. uc_NoPitch:
  308.     call    SetChannelVol
  309.  
  310.  
  311. uc_Ready:       ;ready with updating the channel!!!
  312.  
  313.  
  314. ;---- Check the FX
  315.  
  316.     mov     bx,es:[di+WrkBuff_CurrEvent+ev_cmd]
  317.     mov     es:[di+WrkBuff_LastEvent+ev_cmd+bp],bx
  318.     or      bh,bh
  319.     jz      uc_NoNewLastParam
  320.     mov     es:[di+WrkBuff_LastEvent+ev_lastparams+bp],bh
  321. uc_NoNewLastParam:
  322.     mov     ax,bx
  323.     and     bx,0Fh
  324.     add     bx,bx
  325.     mov     dx,cs:[CmdPtrTab1+bx]
  326.     or      dx,dx
  327.     jz      amd_NoCommand
  328.     push    cx
  329.     call    dx
  330.     pop     cx
  331.  
  332.  
  333. amd_NoCommand:
  334.     cmp     byte ptr es:[di+WrkBuff_CurrEvent+ev_cmd],8
  335.     jz      ap_StillWaiting
  336.     cmp     byte ptr es:[di+WrkBuff_CurrEvent+ev_pitch],0
  337.     jz      ap_StillWaiting
  338.     call    PlayNote
  339.  
  340.  
  341.  
  342. ap_StillWaiting:
  343.     inc     cx
  344.     cmp     cx,9
  345.     jb      ap_ChannelLoop
  346.  
  347.  
  348. ;---- Go next line !
  349.     cmp     cs:[breakstate],0
  350.     jz      ap_GoNormal
  351.  
  352.     mov     al,cs:[breakptn]
  353.     mov     byte ptr es:[di+WrkBuff_CurrPtn],al
  354.     mov     al,cs:[breakline]
  355.     mov     byte ptr es:[di+WrkBuff_CurrLine],al
  356.     or      al,al
  357.     jz      ap_CheckSongLoop
  358.  
  359. ;--- Calculate offset into new pattern
  360.     call    CalcTrackPtr
  361.  
  362.     xor     bx,bx
  363. ap_CalcOffsLoop:
  364.     mov     bp,es:[di+WrkBuff_TrackPtr+bx]
  365.     xor     ch,ch
  366.     mov     cl,byte ptr es:[di+WrkBuff_CurrLine]
  367.     xor     dh,dh                                   ;dh=trackdelay
  368. ap_RowLoop:
  369.     or      dh,dh
  370.     jz      ap_GetNewEvent
  371.     dec     dh
  372.     jmp     ap_GoOn
  373. ap_GetNewEvent:
  374.     mov     al,ds:[bp]
  375.     test    al,128
  376.     jnz     ap_MakeDelay
  377.     add     bp,3
  378.     xor     dh,dh
  379.     jmp     ap_GoOn
  380. ap_MakeDelay:
  381.     inc     bp
  382.     and     al,127
  383.     dec     al
  384.     mov     dh,al
  385. ap_GoOn:
  386.     inc     ch
  387.     cmp     ch,cl
  388.     jb      ap_RowLoop
  389.     mov     es:[di+WrkBuff_TrackPtr+bx],bp
  390.     mov     bp,bx
  391.     shr     bp,1
  392.     or      dh,128
  393.     mov     es:[di+WrkBuff_TrackDelay+bp],dh
  394.     add     bl,2
  395.     cmp     bl,18
  396.     jb      ap_CalcOffsLoop
  397.  
  398.  
  399.     jmp     ap_CheckSongLoop
  400.  
  401. ap_GoNormal:
  402.     inc     byte ptr es:[di+WrkBuff_CurrLine]
  403.     cmp     byte ptr es:[di+WrkBuff_CurrLine],64
  404.     jb      ap_ByeBye
  405.     mov     byte ptr es:[di+WrkBuff_CurrLine],0
  406.     inc     byte ptr es:[di+WrkBuff_CurrPtn]
  407.  
  408. ap_CheckSongLoop:
  409.     mov     al,byte ptr es:[di+WrkBuff_CurrPtn]
  410.     cmp     ds:[si+932],al
  411.     ja      ap_ByeBye
  412.     mov     word ptr es:[di+WrkBuff_CurrPtn],0
  413.  
  414. ap_ByeBye:
  415.     popa
  416. ap_NoAdlibPresent:
  417.     ret
  418.  
  419.  
  420. ap_JustDoTheFX:
  421.     mov     byte ptr es:[di+WrkBuff_SongDelay],al
  422.  
  423. ;---- Check the FX
  424.  
  425.     xor     cx,cx
  426.     xor     bp,bp
  427. ap_FXLoop:
  428.     mov     bx,cx
  429.     test    byte ptr es:WrkBuff_TrackDelay[di+bx],128
  430.     jnz     ap_DontDoIt
  431.     mov     bx,es:[di+WrkBuff_LastEvent+ev_cmd+bp]
  432.     mov     ax,bx
  433.     and     bx,0Fh
  434.     add     bx,bx
  435.     mov     dx,cs:[CmdPtrTab2+bx]
  436.     or      dx,dx
  437.     jz      ap_DontDoIt
  438.     push    cx
  439.     call    dx
  440.     pop     cx
  441. ap_DontDoIt:
  442.     add     bp,LastEventSize
  443.     inc     cx
  444.     cmp     cx,9
  445.     jb      ap_FXLoop
  446.     jmp     ap_ByeBye
  447.  
  448. _AdlibPlayer endp
  449.  
  450.  
  451.  
  452. Adlib_Reset proc near
  453.  
  454.     ;*** Check Adlib ***
  455.  
  456.     mov     dx,388h
  457.     mov     al,2
  458.     out     dx,al
  459.     jmp     $+2
  460.     inc     dl
  461.     mov     al,1
  462.     out     dx,al   ;set timer#1
  463.     jmp     $+2
  464.     dec     dl
  465.     in      al,dx
  466.     and     al,01000000b    ;received??
  467.     jz      ar_CardOK
  468.     ret
  469.  
  470. ar_CardOK:
  471.     mov     cs:[_AdlibState],1
  472.  
  473.  
  474.     mov     bx,1
  475. ar_ResetLoop:
  476.     mov     ax,bx
  477.     and     al,0E0h
  478.     cmp     al,40h
  479.     jnz     ar_ClearReg
  480.     mov     ah,63
  481. ar_ClearReg:
  482.     mov     al,bl
  483.     call    Adlib_OUT
  484.     inc     bl
  485.     jnz     ar_ResetLoop
  486.  
  487.     mov     ax,02001h
  488.     call    Adlib_OUT
  489.     ret
  490. Adlib_Reset endp
  491.  
  492.  
  493.  
  494.  
  495.  
  496. CalcTrackPtr proc near
  497.     mov     bl,es:[di+WrkBuff_CurrPtn]
  498.     xor     bh,bh
  499.     mov     bl,ds:[si+bx+3A6h]      ;current pattern
  500.     imul    bx,18
  501.     mov     cx,9
  502.     lea     bp,WrkBuff_TrackPtr[di]
  503. ctp_ChLoop:
  504.     push    bx
  505.     mov     bx,ds:[si+bx+430h]      ;current track
  506.     add     bx,bx
  507.     mov     ax,es:[di+bx]
  508.     mov     bx,cx
  509.     mov     byte ptr es:[di+WrkBuff_TrackDelay-1+bx],0
  510.     pop     bx
  511.     mov     es:[bp],ax      ;store trackptr
  512.     add     bp,2
  513.     add     bx,2
  514.     dec     cl
  515.     jnz     ctp_ChLoop
  516.     ret
  517. CalcTrackPtr endp
  518.  
  519.  
  520.  
  521.  
  522. CmdPtrTab1      dw offset InitArpeggio
  523.         dw offset SlideFreqUp
  524.         dw offset SlideFreqDown
  525.         dw 0
  526.         dw offset SetInsVol
  527.         dw offset JumpPattern
  528.         dw offset PtnBreak
  529.         dw offset SetSongSpeed
  530.         dw offset InitTonePortamento
  531.         dw offset ExtCmds
  532.         dw 0
  533.         dw 0
  534.         dw 0
  535.         dw 0
  536.         dw 0
  537.         dw 0
  538.  
  539.  
  540.  
  541. ;###### Commands Type#1 #######
  542. ;
  543. ;ah = Parameter of the Command
  544. ;es:[bp] = LastEvent
  545.  
  546.  
  547.  
  548. InitArpeggio:
  549.     mov     byte ptr es:[di+WrkBuff_LastEvent+ev_arpeggio+bp],0
  550.     ret
  551.  
  552. SetInsVol:
  553.     mov     byte ptr es:[di+WrkBuff_LastEvent+ev_vol+bp],ah
  554.     call    SetChannelVol
  555.     ret
  556.  
  557.  
  558. SetSongSpeed:
  559.     or      ah,ah
  560.     jz      sss_Zero
  561.     cmp     ah,32
  562.     jb      sss_Delay
  563.  
  564. sss_Freq:       ;change interrupt frequence
  565.     cmp     cs:[irqmod],1
  566.     jz      sss_polling
  567.     mov     cl,ah
  568.     xor     ch,ch
  569.     mov     dx,0012h
  570.     mov     ax,34DCh
  571.     div     cx
  572.     jmp     sss_Set
  573. sss_Zero:
  574.     mov     ax,-1
  575. sss_Set:
  576.     out     40h,al
  577.     mov     al,ah
  578.     out     40h,al
  579. sss_polling:
  580.     ret
  581.  
  582. sss_Delay:      ;just change the delay value
  583.     mov     es:[di+WrkBuff_CurrSpeed],ah
  584.     mov     byte ptr es:[di+WrkBuff_SongDelay],ah
  585.     ret
  586.  
  587.  
  588.  
  589.  
  590.  
  591. SlideFreqUp:
  592.     mov     bl,cl
  593.  
  594.     mov     al,byte ptr es:[di+WrkBuff_LastEvent+ev_pitch+bp]
  595.     mov     dh,byte ptr es:[di+WrkBuff_LastEvent+ev_oct+bp]
  596.     call    GetFreq
  597.     mov     dx,ax
  598.  
  599.     mov     cl,byte ptr es:[di+WrkBuff_LastEvent+ev_params+bp]
  600.     xor     ch,ch
  601.     add     word ptr es:[di+WrkBuff_LastEvent+ev_pitching+bp],cx
  602.     add     ax,word ptr es:[di+WrkBuff_LastEvent+ev_pitching+bp]
  603.  
  604.     cmp     ax,FreqRange*7+305
  605.     jb      sfu_OK
  606.     mov     ax,FreqRange*7+305
  607.     sub     ax,dx
  608.     mov     word ptr es:[di+WrkBuff_LastEvent+ev_pitching+bp],ax
  609.     mov     ax,FreqRange*7+305
  610. sfu_OK:
  611.     call    SetFreq
  612.     ret
  613.  
  614.  
  615.  
  616. SlideFreqDown:
  617.     mov     bl,cl
  618.     mov     al,byte ptr es:[di+WrkBuff_LastEvent+ev_pitch+bp]
  619.     mov     dh,byte ptr es:[di+WrkBuff_LastEvent+ev_oct+bp]
  620.     call    GetFreq
  621.     mov     dx,ax
  622.  
  623.     mov     cl,byte ptr es:[di+WrkBuff_LastEvent+ev_params+bp]
  624.     xor     ch,ch
  625.     sub     word ptr es:[di+WrkBuff_LastEvent+ev_pitching+bp],cx
  626.     add     ax,word ptr es:[di+WrkBuff_LastEvent+ev_pitching+bp]
  627.  
  628.     or      ax,ax
  629.     jns     short sfd_OK
  630.     not     dx
  631.     mov     word ptr es:[di+WrkBuff_LastEvent+ev_pitching+bp],dx
  632.     xor     ax,ax
  633. sfd_OK:
  634.     call    SetFreq
  635.     ret
  636.  
  637.  
  638.  
  639.  
  640. SetCarrModVol proc near
  641.     mov     al,es:[di+WrkBuff_CurrEvent+ev_params]
  642.     xor     ah,ah
  643.     mov     dl,10
  644.     div     dl
  645.     or      al,al
  646.     jz      short scmv_SetMod
  647.     mov     dh,ah
  648.     xor     ah,ah
  649.     mov     dl,7
  650.     mul     dl
  651.     xor     al,03Fh
  652.     xor     al,al
  653.     mov     es:[di+WrkBuff_CarrVol+bx],al
  654.     mov     ah,dh
  655. scmv_SetMod:
  656.     or      ah,ah
  657.     jz      scmv_byebye
  658.     mov     al,ah
  659.     xor     ah,ah
  660.     mov     dl,7
  661.     mul     dl
  662.     xor     al,3Fh
  663.     mov     es:[di+WrkBuff_ModVol+bx],al
  664. scmv_byebye:
  665.     ret
  666. SetCarrModVol endp
  667.  
  668.  
  669.  
  670.  
  671.  
  672.  
  673.  
  674. InitTonePortamento:
  675.     mov     al,byte ptr es:[di+WrkBuff_CurrEvent+ev_pitch]
  676.     or      al,al
  677.     jz      itp_NoPitch
  678.     mov     dh,byte ptr es:[di+WrkBuff_CurrEvent+ev_oct]
  679.     call    GetFreq
  680.     mov     word ptr es:[di+WrkBuff_LastEvent+ev_tpdest+bp],ax
  681.     call    TonePortamento
  682. itp_NoPitch:
  683.     ret
  684.  
  685.  
  686.  
  687.  
  688.  
  689. TonePortamento:
  690.     push    si
  691.     push    cx
  692.     mov     si,word ptr es:[di+WrkBuff_LastEvent+ev_tpdest+bp]
  693.     mov     al,byte ptr es:[di+WrkBuff_LastEvent+ev_pitch+bp]
  694.     xor     ah,ah
  695.     mov     dh,byte ptr es:[di+WrkBuff_LastEvent+ev_oct+bp]
  696.     call    GetFreq
  697.     mov     dx,ax
  698.     mov     bx,word ptr es:[di+WrkBuff_LastEvent+ev_pitching+bp]
  699.     add     dx,bx
  700.  
  701.     xor     ch,ch
  702.     mov     cl,byte ptr es:[di+WrkBuff_LastEvent+ev_lastparams+bp]
  703.     cmp     dx,si
  704.     ja      tp_down
  705.     jb      tp_up
  706. tp_byebye:
  707.     mov     word ptr es:[di+WrkBuff_LastEvent+ev_pitching+bp],bx
  708.     mov     ax,dx
  709.     pop     bx
  710.     pop     si
  711.     call    SetFreq
  712.     ret
  713.  
  714. tp_up:
  715.     add     bx,cx
  716.     add     dx,cx
  717.     cmp     dx,si
  718.     jbe     tp_byebye
  719.     mov     dx,si
  720.     mov     cx,dx
  721.     sub     cx,ax
  722.     mov     bx,cx
  723.     jmp     tp_byebye
  724.  
  725.  
  726. tp_down:
  727.     sub     bx,cx
  728.     sub     dx,cx
  729.     cmp     dx,si
  730.     jae     tp_byebye
  731.     mov     dx,si
  732.     sub     dx,ax
  733.     mov     bx,dx
  734.     mov     dx,si
  735.     jmp     tp_byebye
  736.  
  737.  
  738. ExtCmdsTab label word
  739.     dw offset CellTrem
  740.     dw offset CellVib
  741.     dw offset SlideVolUp
  742.     dw offset SlideVolDown
  743.     dw offset SlideVolUp
  744.     dw offset SlideVolDown
  745.     dw 0
  746.     dw 0
  747.     dw 0
  748.     dw 0
  749.  
  750. ExtCmds proc near
  751.     mov     al,es:[di+WrkBuff_CurrEvent+ev_params]
  752.     xor     ah,ah
  753.     mov     dl,10
  754.     div     dl
  755.     add     al,al
  756.     xor     ah,ah
  757.     mov     bx,ax
  758.     mov     ax,cs:[ExtCmdsTab+bx]
  759.     or      ax,ax
  760.     jz      ec_dont
  761.     call    ax              ;ah=param
  762. ec_dont:
  763.     ret
  764. ExtCmds endp
  765.  
  766.  
  767. Adlib_BD db 0   ;contents of register BDh
  768.  
  769. CellTrem proc near
  770.     or      ah,ah
  771.     jz      ct_Clear
  772.     or      cs:[Adlib_BD],128
  773.     jmp     ct_set
  774. ct_Clear:
  775.     and     cs:[Adlib_BD],not 128
  776. ct_set:
  777.     mov     ah,cs:[Adlib_BD]
  778.     mov     al,0BDh
  779.     call    Adlib_OUT
  780.     ret
  781. CellTrem endp
  782.  
  783.  
  784. CellVib proc near
  785.     or      ah,ah
  786.     jz      cv_Clear
  787.     or      cs:[Adlib_BD],64
  788.     jmp     ct_set
  789. cv_Clear:
  790.     and     cs:[Adlib_BD],not 64
  791. cv_set:
  792.     jmp     ct_set
  793. CellVib endp
  794.  
  795.  
  796.  
  797.  
  798.  
  799. SlideVolUp proc near
  800.     mov     bh,es:[di+WrkBuff_LastEvent+ev_vol+bp]
  801.     mov     al,es:[di+WrkBuff_LastEvent+ev_params+bp]
  802.     xor     ah,ah
  803.     mov     bl,10
  804.     div     bl
  805.  
  806.     add     bh,ah
  807.     cmp     bh,63
  808.     jbe     sv_done
  809.     mov     bh,63
  810. sv_done:
  811.     mov     es:[di+WrkBuff_LastEvent+ev_vol+bp],bh
  812. sv_hallo:
  813.     call    SetChannelVol
  814.     ret
  815. SlideVolUp endp
  816.  
  817.  
  818. SlideVolDown proc near
  819.     mov     bh,es:[di+WrkBuff_LastEvent+ev_vol+bp]
  820.  
  821.     mov     al,es:[di+WrkBuff_LastEvent+ev_params+bp]
  822.     xor     ah,ah
  823.     mov     bl,10
  824.     div     bl
  825.  
  826.     sub     bh,ah
  827.     jns     sd_done
  828.     xor     bh,bh
  829. sd_done:
  830.     mov     es:[di+WrkBuff_LastEvent+ev_vol+bp],bh
  831.  
  832.     call    SetChannelVol
  833.     ret
  834. SlideVolDown endp
  835.  
  836.  
  837.  
  838.  
  839. breakstate      db 0
  840. breakline       db 0
  841. breakptn        db 0
  842.  
  843. PtnBreak proc near
  844.     mov     al,es:[di+WrkBuff_CurrEvent+ev_params]
  845.     and     al,3Fh
  846.     mov     cs:[breakline],al
  847.     mov     al,byte ptr es:[di+WrkBuff_CurrPtn]
  848.     inc     al
  849.     mov     cs:[breakptn],al
  850.     mov     cs:[breakstate],1
  851.     ret
  852. PtnBreak endp
  853.  
  854.  
  855. JumpPattern proc near
  856.     mov     al,es:[di+WrkBuff_CurrEvent+ev_params]
  857.     mov     cs:[breakptn],al
  858.     mov     cs:[breakline],0
  859.     mov     cs:[breakstate],1
  860.     ret
  861. JumpPattern endp
  862.  
  863.  
  864.  
  865.  
  866.  
  867.  
  868. CmdPtrTab2      dw offset Arpeggio
  869.         dw offset SlideFreqUp
  870.         dw offset SlideFreqDown
  871.         dw 0
  872.         dw 0
  873.         dw 0
  874.         dw 0
  875.         dw 0
  876.         dw offset TonePortamento
  877.         dw offset ExtCmds2
  878.         dw 0
  879.         dw 0
  880.         dw 0
  881.         dw 0
  882.         dw 0
  883.         dw 0
  884.  
  885.  
  886. ;###### Commands Type#2 #######
  887. ;
  888. ;ah = Parameter of the Command
  889. ;es:[bp] = LastEvent
  890.  
  891.  
  892.  
  893. Arpeggio:
  894.     mov     al,ah
  895.     and     ax,07Fh
  896.     jz      arp_OFF
  897.     mov     bl,10
  898.     div     bl
  899.     mov     bh,byte ptr es:[di+WrkBuff_LastEvent+ev_arpeggio+bp]
  900.     mov     bl,bh
  901.     inc     bl
  902.     cmp     bl,3
  903.     jb      arp_goon
  904.     xor     bl,bl
  905. arp_goon:
  906.     mov     byte ptr es:[di+WrkBuff_LastEvent+ev_arpeggio+bp],bl
  907.  
  908.     cmp     bh,1
  909.     jz      arp_PlayFirst
  910.     cmp     bh,2
  911.     jz      arp_PlaySecond
  912.  
  913. arp_PlayNormal:
  914.     mov     al,byte ptr es:[di+WrkBuff_LastEvent+ev_pitch+bp]
  915.     jmp     ActualPitch
  916.  
  917. arp_PlayFirst:
  918.     add     al,byte ptr es:[di+WrkBuff_LastEvent+ev_pitch+bp]
  919.     jmp     ActualPitch
  920.  
  921. arp_PlaySecond:
  922.     mov     al,byte ptr es:[di+WrkBuff_LastEvent+ev_pitch+bp]
  923.     add     al,ah
  924.  
  925.  
  926. ActualPitch:    ;Play the Arpeggio!!!
  927.     mov     dh,byte ptr es:[di+WrkBuff_LastEvent+ev_oct+bp]
  928.     cmp     al,12
  929.     jbe     arp_PitchOK
  930.     sub     al,12
  931.     inc     ah
  932. arp_PitchOK:
  933.     cmp     dh,8
  934.     jb      arp_OctOK
  935.     mov     dh,7
  936.     mov     al,12
  937. arp_OctOK:
  938.     mov     bl,dl
  939.     call    GetFreq
  940.     add     ax,word ptr es:[di+WrkBuff_LastEvent+ev_pitching+bp]
  941.     mov     bl,cl
  942.     call    SetFreq
  943. arp_OFF:
  944.     ret
  945.  
  946.  
  947.  
  948. ExtCmdsTab2 label word
  949.     dw 0
  950.     dw 0
  951.     dw offset SlideVolUp
  952.     dw offset SlideVolDown
  953.     dw 0
  954.     dw 0
  955.     dw 0
  956.     dw 0
  957.     dw 0
  958.     dw 0
  959.  
  960. ExtCmds2 proc near
  961.     mov     al,es:[di+WrkBuff_LastEvent+ev_params+bp]
  962.     xor     ah,ah
  963.     mov     dl,10
  964.     div     dl
  965.     add     al,al
  966.     xor     ah,ah
  967.     mov     bx,ax
  968.     mov     ax,cs:[ExtCmdsTab2+bx]
  969.     or      ax,ax
  970.     jz      ec2_dont
  971.     call    ax              ;ah=param
  972. ec2_dont:
  973.  
  974.     ret
  975. ExtCmds2 endp
  976.  
  977.  
  978.  
  979.  
  980.  
  981.  
  982.  
  983.  
  984.  
  985.  
  986. ;al=note
  987. ;dh=octave
  988. ;->ax is absolute freq
  989.  
  990. GetFreq proc near
  991.     push    si cx
  992.  
  993.     dec     al
  994.     add     al,al
  995.     xor     ah,ah
  996.     mov     si,ax
  997.     mov     cx,cs:[FreqParams+si]
  998.     sub     cx,FreqStart
  999.  
  1000.     mov     al,dh
  1001.     and     ax,7
  1002.     mov     dx,FreqRange
  1003.     mul     dx
  1004.     add     ax,cx
  1005.  
  1006.     pop     cx si
  1007.     ret
  1008. GetFreq endp
  1009.  
  1010.  
  1011.  
  1012. ;ax=absolute freq
  1013. ;bl=channel
  1014.  
  1015. SetFreq proc near
  1016.     or      ax,ax
  1017.     jns     short sf_ok
  1018.     xor     ax,ax
  1019. sf_ok:
  1020.     cmp     ax,FreqRange*7+305
  1021.     jb      sf_ok2
  1022.     mov     ax,FreqRange*7+305
  1023. sf_ok2:
  1024.  
  1025.  
  1026.     push    si cx
  1027.     mov     cx,FreqRange
  1028.     xor     dx,dx
  1029.     div     cx              ; extracts octave in AX and freq. in DX
  1030.     add     dx,FreqStart
  1031.  
  1032.     mov     cl,al
  1033.     mov     al,0A0h
  1034.     add     al,bl
  1035.     mov     ah,dl
  1036.     call    Adlib_OUT
  1037.  
  1038.     mov     al,0B0h
  1039.     add     al,bl
  1040.     mov     ah,cl
  1041.     add     ah,ah
  1042.     add     ah,ah
  1043.     or      ah,dh
  1044.     or      ah,100000b
  1045.     call    Adlib_OUT
  1046.  
  1047.     pop     cx si
  1048.     ret
  1049. SetFreq endp
  1050.  
  1051.  
  1052.  
  1053. ;al=register
  1054. ;ah=value
  1055. ;
  1056. Adlib_OUT proc near
  1057.     push    ax dx
  1058.     mov     dx,388h
  1059.     out     dx,al
  1060.     rept    6
  1061.     in      al,dx
  1062.     endm
  1063.  
  1064.     inc     dl
  1065.     mov     al,ah
  1066.     out     dx,al
  1067.     dec     dl
  1068.     rept    22
  1069.     in      al,dx
  1070.     endm
  1071.     pop     dx ax
  1072.     ret
  1073. Adlib_OUT endp
  1074.  
  1075.  
  1076.  
  1077.  
  1078.  
  1079. ;Plays the current event
  1080. ;
  1081. ;es:[di+WrkBuff_CurrEvent
  1082. ;cl=Channel
  1083. ;
  1084.  
  1085. PlayNote proc near
  1086.     push    bp
  1087.     mov     bx,cx
  1088.  
  1089. ;--- get the pointer to current instrument in ds:bp !
  1090.     mov     al,byte ptr es:[di+WrkBuff_CurrEvent+ev_sam]
  1091.     xor     ah,ah
  1092.     mov     bp,ax
  1093.     dec     bp
  1094.     js      pn_Abort
  1095.     imul    bp,34
  1096.     lea     bp,[bp+si+30h+23]
  1097.  
  1098.     mov     al,ds:[bp+1]
  1099.     and     al,03Fh
  1100.     mov     es:[di+WrkBuff_ModVol+bx],al
  1101.     mov     al,ds:[bp+6]
  1102.     and     al,03Fh
  1103.     mov     es:[di+WrkBuff_CarrVol+bx],al
  1104.  
  1105.     cmp     byte ptr es:[di+WrkBuff_CurrEvent+ev_cmd],3
  1106.     jnz     pn_DontManipulate
  1107.     call    SetCarrModVol
  1108. pn_DontManipulate:
  1109.     mov     al,cs:[ChannelOffs+bx]
  1110.     mov     dl,4
  1111. pn_Loop:
  1112.     mov     ah,ds:[bp]
  1113.     call    Adlib_OUT
  1114.     add     al,3
  1115.     mov     ah,ds:[bp+5]
  1116.     call    Adlib_OUT
  1117.     add     al,20h-3
  1118.     inc     bp
  1119.     dec     dl
  1120.     jnz     pn_Loop
  1121.  
  1122.     add     al,40h          ; do E0 range now
  1123.     mov     ah,ds:[bp]
  1124.     call    Adlib_OUT
  1125.     add     al,3
  1126.     mov     ah,ds:[bp+5]
  1127.     call    Adlib_OUT
  1128.  
  1129.  
  1130.     call    SetChannelVol
  1131.  
  1132.     mov     al,0C0h
  1133.     add     al,bl
  1134.     mov     ah,ds:[bp+6]
  1135.     call    Adlib_OUT
  1136.  
  1137.     mov     al,es:[di+WrkBuff_CurrEvent+ev_pitch]
  1138.     xor     ah,ah
  1139.     dec     ax
  1140.     add     ax,ax
  1141.     mov     bp,ax
  1142.     mov     dx,cs:[FreqParams+bp]
  1143.  
  1144.     mov     al,0A0h
  1145.     add     al,bl
  1146.     mov     ah,dl
  1147.     call    Adlib_OUT
  1148.  
  1149.     mov     al,0B0h
  1150.     add     al,bl
  1151.     mov     ah,dh
  1152.     call    Adlib_OUT
  1153.     mov     dl,es:[di+WrkBuff_CurrEvent+ev_oct]
  1154.     add     dl,dl
  1155.     add     dl,dl
  1156.     or      ah,dl
  1157.     or      ah,100000b
  1158.     call    Adlib_OUT       ;...und mit neuen Daten anschalten
  1159.  
  1160.  
  1161.  
  1162. pn_Abort:
  1163.     pop     bp
  1164.     ret
  1165. PlayNote endp
  1166.  
  1167. ChannelOffs     db      20h,21h,22h,28h,29h,2ah,30h,31h,32h
  1168.  
  1169.  
  1170.  
  1171.  
  1172. VolTab  db 0,95/31,182/31,262/31,336/31,405/31,470/31,530/31,587/31,641/31
  1173.     db 693/31,741/31,788/31,832/31,875/31,916/31,955/31,993/31,1029/31
  1174.     db 1064/31,1098/31,1131/31,1163/31,1193/31,1223/31,1252/31,1280/31
  1175.     db 1308/31,1335/31,1360/31,1386/31,1410/31,1435/31,1458/31,1481/31
  1176.     db 1504/31,1526/31,1547/31,1568/31,1589/31,1609/31,1629/31,1648/31
  1177.     db 1667/31,1686/31,1704/31,1722/31,1740/31,1757/31,1774/31,1791/31
  1178.     db 1808/31,1824/31,1840/31
  1179.     db 1856/31,1871/31,1887/31,1902/31,1916/31,1931/31,1945/31,1960/31
  1180.     db 1974/31,1980/31
  1181.  
  1182.  
  1183.  
  1184.  
  1185. ;Sets the lastvol of channel cl
  1186. ;
  1187.  
  1188. SetChannelVol proc near
  1189.     pusha
  1190.  
  1191. ;--- get the pointer to current instrument in ds:bp !
  1192.     imul    bx,cx,LastEventSize
  1193.     mov     al,byte ptr es:[di+WrkBuff_LastEvent+ev_sam+bx]
  1194.     xor     ah,ah
  1195.     mov     bp,ax
  1196.     dec     bp
  1197.     js      scv_Dont
  1198.     imul    bp,34
  1199.     lea     bp,[bp+si+30h+23]
  1200.  
  1201.     mov     bl,byte ptr es:[di+WrkBuff_LastEvent+ev_vol+bx]
  1202.     xor     bh,bh
  1203.     mov     dl,cs:[VolTab+bx]
  1204.  
  1205.     mov     bx,cx
  1206.     mov     dh,cs:[ChannelOffs+bx]
  1207.     add     dh,20h
  1208.  
  1209.     mov     ah,dl
  1210.     xor     ah,3Fh
  1211.     mov     al,byte ptr es:[di+WrkBuff_CarrVol+bx]
  1212.     and     al,3Fh
  1213.     add     ah,al
  1214.     cmp     ah,3Fh
  1215.     jbe     scv_OK2
  1216.     mov     ah,3Fh
  1217. scv_OK2:
  1218.     mov     al,byte ptr ds:[bp+6]           ;Carrier
  1219.     and     al,not 3Fh
  1220.     or      ah,al
  1221.     mov     al,dh
  1222.     add     al,3
  1223.     call    Adlib_OUT
  1224.  
  1225.     test    byte ptr ds:[bp+10],1
  1226.     jz      scv_Serial
  1227.  
  1228. scv_Parallel:   ;Connection is ON!!!
  1229.     mov     ah,dl
  1230.     xor     ah,3Fh
  1231.     mov     al,byte ptr es:[di+WrkBuff_ModVol+bx]
  1232.     and     al,3Fh
  1233.     add     ah,al
  1234.     cmp     ah,3Fh
  1235.     jbe     scv_OK
  1236.     mov     ah,3Fh
  1237. scv_OK:
  1238.     mov     al,byte ptr ds:[bp+1]                   ;Mod
  1239.     and     al,not 3Fh
  1240.     or      ah,al
  1241.     mov     al,dh
  1242.     call    Adlib_OUT
  1243.     jmp     scv_Dont
  1244.  
  1245.  
  1246. scv_Serial:     ;Connection is OFF!!!
  1247.     mov     ah,byte ptr ds:[bp+1]                   ;Mod
  1248.     and     ah,not 3Fh
  1249.     or      ah,byte ptr es:[di+WrkBuff_ModVol+bx]
  1250.     mov     al,dh
  1251.     call    Adlib_OUT
  1252.  
  1253. scv_Dont:
  1254.  
  1255.     popa
  1256.     ret
  1257. SetChannelVol endp
  1258.  
  1259.     end
  1260.